package com.happy.unitconvert.common.interceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.UUID;

/**
 * 请求拦截器
 * 用于日志追踪、请求统计等
 */
public class RequestInterceptor implements HandlerInterceptor {

  private static final Logger logger = LoggerFactory.getLogger(RequestInterceptor.class);

  private static final String REQUEST_ID_HEADER = "X-Request-ID";
  private static final String REQUEST_ID_MDC_KEY = "requestId";
  private static final String START_TIME_ATTRIBUTE = "startTime";

  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
    // 生成或获取请求ID
    String requestId = request.getHeader(REQUEST_ID_HEADER);
    if (requestId == null || requestId.trim().isEmpty()) {
      requestId = UUID.randomUUID().toString().replace("-", "");
    }

    // 设置MDC用于日志追踪
    MDC.put(REQUEST_ID_MDC_KEY, requestId);

    // 在响应头中添加请求ID
    response.setHeader(REQUEST_ID_HEADER, requestId);

    // 记录请求开始时间
    request.setAttribute(START_TIME_ATTRIBUTE, System.currentTimeMillis());

    // 记录请求信息
    logger.info("Request Start - Method: {}, URI: {}, RemoteAddr: {}, UserAgent: {}",
        request.getMethod(),
        request.getRequestURI(),
        getClientIpAddress(request),
        request.getHeader("User-Agent"));

    return true;
  }

  @Override
  public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
    try {
      // 计算请求处理时间
      Long startTime = (Long) request.getAttribute(START_TIME_ATTRIBUTE);
      long processingTime = startTime != null ? System.currentTimeMillis() - startTime : 0;

      // 记录请求完成信息
      if (ex != null) {
        logger.error("Request Error - Method: {}, URI: {}, Status: {}, Time: {}ms, Error: {}",
            request.getMethod(),
            request.getRequestURI(),
            response.getStatus(),
            processingTime,
            ex.getMessage());
      } else {
        logger.info("Request End - Method: {}, URI: {}, Status: {}, Time: {}ms",
            request.getMethod(),
            request.getRequestURI(),
            response.getStatus(),
            processingTime);
      }
    } finally {
      // 清理MDC
      MDC.clear();
    }
  }

  /**
   * 获取客户端真实IP地址
   */
  private String getClientIpAddress(HttpServletRequest request) {
    String xForwardedFor = request.getHeader("X-Forwarded-For");
    if (xForwardedFor != null && !xForwardedFor.isEmpty() && !"unknown".equalsIgnoreCase(xForwardedFor)) {
      return xForwardedFor.split(",")[0].trim();
    }

    String xRealIp = request.getHeader("X-Real-IP");
    if (xRealIp != null && !xRealIp.isEmpty() && !"unknown".equalsIgnoreCase(xRealIp)) {
      return xRealIp;
    }

    return request.getRemoteAddr();
  }
}
